package com.wjc.wiki.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wjc.wiki.entity.Content;
import com.wjc.wiki.entity.Doc;
import com.wjc.wiki.entity.DocExample;
import com.wjc.wiki.exception.BusinessException;
import com.wjc.wiki.exception.BusinessExceptionCode;
import com.wjc.wiki.mapper.ContentMapper;
import com.wjc.wiki.mapper.DocMapper;
import com.wjc.wiki.mapper.DocMapperCust;
import com.wjc.wiki.req.DocQueryReq;
import com.wjc.wiki.req.DocSaveReq;
import com.wjc.wiki.resp.DocQueryResp;
import com.wjc.wiki.resp.PageResp;
import com.wjc.wiki.util.CopyUtil;
import com.wjc.wiki.util.RedisUtil;
import com.wjc.wiki.util.RequestContext;
import com.wjc.wiki.util.SnowFlake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;

@Service
public class DocService {

    private static final Logger LOG= LoggerFactory.getLogger(DocService.class);

    @Resource
    private DocMapper docMapper;

    @Resource
    private ContentMapper contentMapper;

    @Resource
    private DocMapperCust docMapperCust;

    @Resource
    private SnowFlake snowFlake;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private WsService wsService;

//    @Resource
//    private RocketMQTemplate rocketMQTemplate;

    public PageResp<DocQueryResp> list(DocQueryReq req){

        DocExample docExample =new DocExample();
        DocExample.Criteria criteria=docExample.createCriteria();

        //将查询到的对象转换为docresp,复制doc对象到docresp
        PageHelper.startPage(req.getPage(),req.getSize());
        List<Doc> docList = docMapper.selectByExample(docExample);

        PageInfo<Doc> pageInfo=new PageInfo<>(docList);
        LOG.info("总行数:{}",pageInfo.getTotal());
        LOG.info("总页数:{}",pageInfo.getPages());

        //列表复制
        List<DocQueryResp> docRespList =CopyUtil.copyList(docList, DocQueryResp.class);

        PageResp<DocQueryResp> pageResq=new PageResp();
        pageResq.setTotal(pageInfo.getTotal());
        pageResq.setList(docRespList);

        return pageResq;
    }

    //保存
    //添加事务注解
    @Transactional
    public void save(DocSaveReq req){
        Doc doc =CopyUtil.copy(req,Doc.class);
        Content content =CopyUtil.copy(req,Content.class);
        if (!ObjectUtils.isEmpty(req.getId())){//动态sql,如果req的id不为空,更新 否则新增
            //新增
            docMapper.updateByPrimaryKey(doc);
            int count=contentMapper.updateByPrimaryKeyWithBLOBs(content);
            if(count==0){
                contentMapper.insert(content);
            }
        }else{
            //同时对两张表有增删改的操作,就要考虑加事务，否则会造成数据不准确
            doc.setId(snowFlake.nextId());
            doc.setViewCount(0);
            doc.setVoteCount(0);
            docMapper.insert(doc);

            content.setId(doc.getId());
            contentMapper.insert(content);

        }

    }

    public List<DocQueryResp> all(Long ebookId){

        DocExample docExample =new DocExample();
        docExample.createCriteria().andEbookIdEqualTo(ebookId);
        DocExample.Criteria criteria=docExample.createCriteria();
        //将查询到的对象转换为docresp,复制doc对象到docresp
        List<Doc> docList = docMapper.selectByExample(docExample);
        List<DocQueryResp> docRespList =CopyUtil.copyList(docList, DocQueryResp.class);
        return docRespList;
    }

    public void delete(Long id){
        docMapper.deleteByPrimaryKey(id);
    }
    public void delete(List<String> ids){
        DocExample docExample =new DocExample();
        DocExample.Criteria criteria=docExample.createCriteria();
        criteria.andIdIn(ids);
        docMapper.deleteByExample(docExample);
    }

    public String findContent(Long id){
        Content content = contentMapper.selectByPrimaryKey(id);
        docMapperCust.increaseViewCount(id);//文档阅读数+1
        if (ObjectUtils.isEmpty(content)) {
            return "";
        } else {
            return content.getContent();
        }
    }

    public void vote(Long id){
        //远程ip+doc.id 作为key，24小时不能重复
        String ip = RequestContext.getRemoteAddr();
        //判断是否存在key,若不存在则添加,若存在则抛出异常:已经点赞过。
        if(redisUtil.validateRepeat("DOC_VOTE_"+id+"_"+ip,3600*24)){
            docMapperCust.increaseVoteCount(id);
        }else{
            throw  new BusinessException(BusinessExceptionCode.VOTE_REPEAT);
        }
        //推送消息到websocket,若websocket链接过多则会妨碍vote方法返回给controller,导致前端的点赞数+1延迟
//        Doc docDb=docMapper.selectByPrimaryKey(id);
//        String info="["+docDb.getName()+"]"+ "被点赞!";
//        webSocketServer.sendInfo(info);

        //推送消息
        Doc docDb=docMapper.selectByPrimaryKey(id);
        String info="["+docDb.getName()+"]"+ "被点赞!";
        //获取日志流水号
        String logId= MDC.get("LOG_ID");
        wsService.sendInfo(info,logId);
        //使用rocketmq发送
//        rocketMQTemplate.convertAndSend("VOTE_TOPIC",info);

    }



    public void updateEbookInfo(){
        docMapperCust.updateEbookInfo();
    }

}
